package list

import (
	"errors"
	"fmt"
	"reflect"
	"time"
)

//比较函数定义
type sortFunc func(a, b interface{}) bool

//顺序列表节点
type OrderList struct {
	cmp  sortFunc
	Head *orderListNode
}

//return a>b, 有大到小排列
func DefaultMaxFunc(a, b interface{}) bool {
	return DefaultMinFunc(b, a)
}

//return a<b,由小到大排列
func DefaultMinFunc(a, b interface{}) bool {
	valueA := reflect.ValueOf(a)
	valueB := reflect.ValueOf(b)
	if valueA.Type() != valueB.Type() {
		panic(errors.New("类型不匹配"))
	}
	switch valueA.Type().Name() {
	case "int8", "int16", "int", "int64", "int32":
		return valueA.Int() < valueB.Int()
	case "float32", "float64":
		return valueA.Float() < valueB.Float()
	case "uint8", "uint16", "uint64", "uint", "uint32":
		return valueA.Uint() < valueB.Uint()
	case "string":
		return valueA.String() < valueB.String()
	case "time.Time", "Time":
		Ta := a.(time.Time)
		Tb := b.(time.Time)
		return Ta.Sub(Tb) < 0
	default:
		panic(errors.New("类型不匹配"))
	}
	return false
}

/*
创建一个空的顺序列表
初始化时需要指定一个比较函数，为空的话就使用默认的比较函数但是只能操作普通类型
如果有自定义类型必须指定该比较函数表明你需要用来排序的方式
*/
func NewOrderList(f sortFunc) *OrderList {
	if f == nil {
		return &OrderList{
			cmp:  DefaultMinFunc,
			Head: nil,
		}
	} else {
		return &OrderList{
			cmp:  f,
			Head: nil,
		}
	}
}

/*
将数据插入顺序列表，如果插入的类型与已有数据类型不匹配会抛出异常
*/
func (l *OrderList) InsertOrderList(data interface{}) bool {
	//insertNode := l.Head
	if l.Head == nil {
		newNode := newOrderListNode(data)
		l.Head = newNode
		return true
	}
	beforeNode := l.Head
	insertNode := beforeNode.Next
	for {
		//if insertNode == nil{
		//	break
		//}
		//fmt.Println(beforeNode.Data)
		if l.cmp(beforeNode.Data, data) {
			if insertNode == nil {
				newNode := newOrderListNode(data)
				beforeNode.Next = newNode
				return true
			}
			beforeNode = insertNode
			insertNode = beforeNode.Next
			continue
		} else {
			if beforeNode == l.Head {
				newNode := newOrderListNode(data)
				newNode.Next = l.Head
				l.Head = newNode
				return true
			}
			newNode := newOrderListNode(data)
			//if insertNode!=nil{
			newNode.Next = insertNode
			beforeNode.Next = newNode

			//newNode.Next = insertNode
			return true
			//break
		}
	}
	//if beforeNode == l.Head{
	//	newNode := newOrderListNode(data)
	//	newNode.Next = l.Head
	//	l.Head = newNode
	//	return true
	//}
	//newNode := newOrderListNode(data)
	////if insertNode!=nil{
	//newNode.Next = insertNode
	//beforeNode.Next = newNode
	//
	////newNode.Next = insertNode
	//return true
}

//从头部获取一个元素
func (l *OrderList) PopOrderList() (data interface{}, err error) {
	if l.Head == nil {
		return nil, errors.New("have not data.")
	}
	data = l.Head.Data
	l.Head = l.Head.Next
	return
}

//遍历链表
func (l *OrderList) PrintOrderList() {
	node := l.Head
	for {
		if node == nil {
			break
		}
		fmt.Println(node.Data)
		node = node.Next
	}
}
